﻿using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RuoVea.DynamicWebApi;
using RuoVea.ExCache;
using RuoVea.ExDto;
using RuoVea.ExEnum;
using RuoVea.ExSugar;
using RuoVea.ExSugar.Dto;
using RuoVea.ExUtil;
using RuoVea.OmiApi.Config.Entitys;
using RuoVea.OmiApi.Config.Language;
using RuoVea.OmiApi.Config.Service.Dto;
using RuoVea.OmiApi.Dict;
using System.ComponentModel;
using exDtoi18n = RuoVea.ExDto.Language.i18n;

namespace RuoVea.OmiApi.Config.Service;

/// <summary>
/// 参数配置表 🔷
/// </summary>
[ApiExplorerSettings(GroupName = "system")]
public class SysConfigService : IApplicationService
{
    private readonly SugarRepository<SysConfig> _thisRepository;
    /// <summary>
    /// 参数配置表
    /// </summary>
    /// <param name="thisRepository"></param>
    public SysConfigService(SugarRepository<SysConfig> thisRepository) => _thisRepository = thisRepository;

    /// <summary>
    /// 查询所有/分页🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<PageResult<SysConfigDto>> GetPagesAsync([FromQuery] SysConfigParam data)
    {

        var query = await _thisRepository.AsQueryable()
            .Where(u => u.IsDelete == IsDelete.N)
            .WhereIF(data.IsDisable.HasValue, u => u.IsDisable == data.IsDisable)
            .WhereIF(data.SysFlag.HasValue, u => u.SysFlag == data.SysFlag)
            .WhereIF(!string.IsNullOrEmpty(data.Name?.Trim()), u => u.Name.Contains(data.Name.Trim()))
            .WhereIF(!string.IsNullOrEmpty(data.Code?.Trim()), u => u.Code.Contains(data.Code.Trim()))
            .WhereIF(!string.IsNullOrEmpty(data.GroupCode?.Trim()), u => u.GroupCode.Contains(data.GroupCode.Trim()))
            .OrderByDescending(x => x.Id)
            .ToPageAsync<SysConfig, SysConfigDto>(data.PageNo, data.PageSize);
        return query;
    }

    /// <summary>
    /// 根据主键查询🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<SysConfigDto> GetDataAsync(EntityBaseIdDto data)
    {
        var model = await _thisRepository.GetFirstAsync(x => x.IsDelete == IsDelete.N && x.Id == data.Id);
        return model.Adapt<SysConfigDto>();
    }

    /// <summary>
    /// 获取系统参数配置列表
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<List<SysConfig>> GetDataList()
    {
        return await _thisRepository.AsQueryable().Where(u => u.IsDelete == IsDelete.N).ToListAsync();
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task<bool> AddDataAsync(SysConfigInputDto data)
    {
        var result = await _thisRepository.Context.Ado.UseTranAsync(async () =>
        {
            var isExist = await _thisRepository.AsQueryable()
            .AnyAsync(u => u.Name == data.Name || u.Code == data.Code);

            if (isExist)
                throw new ArgumentException(ErrorEnum.D9000.GetDescription(exDtoi18n.ResourceManager));

            var config = data.Adapt<SysConfig>();
            return await _thisRepository.InsertAsync(config);
        });
        return result.IsSuccess && result.Data;
    }

    /// <summary>
    /// 修改🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public virtual async Task UpdateDataAsync(SysConfigInputDto data)
    {
        // 添加ID验证
        if (data.Id <= 0)
            throw new ArgumentException(exDtoi18n.idrequired);

        var isExist = await _thisRepository.AsQueryable().AnyAsync(u => (u.Name == data.Name || u.Code == data.Code) && u.Id != data.Id);
        if (isExist)
            throw new ArgumentException(ErrorEnum.D9000.GetDescription(exDtoi18n.ResourceManager));

        var config = data.Adapt<SysConfig>();

        await _thisRepository.UpdateAsync(config);
        //更新缓存
        var value = config?.Value ?? "";
        await CacheFactery.Cache.WriteAsync($"{CacheConst.KeyConfig}{data.Code}", value);
    }

    /// <summary>
    /// 删除🔹
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    [HttpDelete]
    public virtual async Task DeleteDataAsync([FromBody] EntityBaseIdDto data)
    {
        var config = await _thisRepository.GetFirstAsync(u => u.Id == data.Id);
        if (config == null)
            throw new ArgumentException(ErrorEnum.D1002.GetDescription(exDtoi18n.ResourceManager));
        // 禁止删除系统参数
        if (config.SysFlag == YesOrNot.Y)
            throw new ArgumentException(ErrorEnum.D9001.GetDescription(exDtoi18n.ResourceManager));
        await _thisRepository.DeleteAsync(m => data.Id == m.Id);
        //删除缓存
        await CacheFactery.Cache.DelAsync($"{CacheConst.KeyConfig}{config.Code}");
    }

    /// <summary>
    /// 批量删除参数配置 🔹
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [DisplayName("批量删除参数配置")]
    public async Task BatchDelete(List<long> ids)
    {
        // 先查询所有符合条件的记录
        var configs = await _thisRepository.GetListAsync(u =>
            ids.Contains(u.Id) && u.SysFlag != YesOrNot.Y);

        if (!configs.Any()) return;

        // 批量删除
        await _thisRepository.DeleteAsync(configs);

        // 批量清除缓存
        foreach (var config in configs)
        {
            await CacheFactery.Cache.DelAsync($"{CacheConst.KeyConfig}{config.Code}");
        }
    }
    /// <summary>
    /// 获取配置信息
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    [NonAction]
    public async Task<string> GetConfigCache(string code)
    {
        var value = await CacheFactery.Cache.ReadAsStringAsync($"{CacheConst.KeyConfig}{code}");
        if (string.IsNullOrEmpty(value))
        {
            var config = await _thisRepository.AsQueryable().Where(x => x.IsDelete == IsDelete.N && x.Code == code).FirstAsync();
            value = config?.Value;
            if (!string.IsNullOrWhiteSpace(value))
            {
                await CacheFactery.Cache.WriteAsync($"{CacheConst.KeyConfig}{config.Code}", value);
            }
        }
        return value;
    }

    #region NonAction
    /// <summary>
    /// 获取演示环境开关是否开启，默认为false🔹
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    public async Task<bool> GetDemoEnvFlag()
    {
        var value = await GetConfigCache("dilon_demo_env_flag");
        if (value == null) throw new ArgumentException($"{i18n.dict_env_switch}:dilon_demo_env_flag");
        _ = bool.TryParse(value, out var result);
        return result;
    }

    /// <summary>
    /// 获取验证码开关标识
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<bool> GetCaptchaOpenFlag()
    {
        var value = await GetConfigCache("dilon_captcha_open");
        if (value == null) throw new ArgumentException($"{i18n.dict_captcha_switch}:dilon_captcha_open");
        _ = bool.TryParse(value, out var result);
        return result;
    }

    /// <summary>
    /// 获取默认密码
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<string> GetDefault_Password()
    {
        var value = await GetConfigCache("dilon_default_password");
        if (value == null) throw new ArgumentException($"{i18n.dict_default_password}:dilon_default_password");
        return value;
    }
    /// <summary>
    /// 开放注册页面
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<bool> GetEnableRegister()
    {
        var value = await GetConfigCache("enable_register");
        if (value == null) throw new ArgumentException($"{i18n.open_register_page}:enable_register");
        _ = bool.TryParse(value, out var result);
        return result;
    }
    /// <summary>
    /// 开放找回密码页面
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<bool> GetEnableForgotPassword()
    {
        var value = await GetConfigCache("enable_forgot_password");
        if (value == null) throw new ArgumentException($"{i18n.open_forgot_password}:enable_forgot_password");
        _ = bool.TryParse(value, out var result);
        return result;
    }
    #endregion

    /// <summary>
    /// 记录操作日志
    /// </summary>
    /// <returns></returns>
    [NonAction]
    public async Task<bool> GetSysOplog()
    {
        var value = await GetConfigCache("sys_oplog");
        if (value == null) throw new ArgumentException($"{i18n.log_operation}:sys_oplog");
        _ = bool.TryParse(value, out var result);
        return result;
    }
    /// <summary>
    /// 更新参数配置值
    /// </summary>
    /// <param name="code"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    [NonAction]
    public async Task UpdateConfigValue(string code, string value)
    {
        var config = await _thisRepository.GetFirstAsync(u => u.Code == code);
        if (config == null) return;

        config.Value = value;
        await _thisRepository.AsUpdateable(config).ExecuteCommandAsync();

      await CacheFactery.Cache.DelAsync($"{CacheConst.KeyConfig}{config.Code}");
    }

    /// <summary>
    /// 获取参数配置值
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    [NonAction]
    public async Task<T> GetConfigValueCache<T>(string code)
    {
        if (string.IsNullOrWhiteSpace(code))
            return default;

        var cacheKey = $"{CacheConst.KeyConfig}{code}";
        var value = await CacheFactery.Cache.ReadAsStringAsync(cacheKey);

        if (string.IsNullOrEmpty(value))
        {
            var config = await _thisRepository.GetFirstAsync(u => u.Code == code);
            value = config?.Value;

            if (!string.IsNullOrEmpty(value))
            {
                await CacheFactery.Cache.WriteAsync(cacheKey, value);
            }
        }

        if (string.IsNullOrWhiteSpace(value))
            return default;

        return (T)Convert.ChangeType(value, typeof(T));
    }

    /// <summary>
    /// 获取分组列表
    /// </summary>
    /// <param name="groupCode"></param>
    /// <returns></returns>
    [DisplayName("获取分组列表")]
    public async Task<List<string>> GetGroupList(string groupCode)
    {
        return await _thisRepository.AsQueryable()
            .Where(u => u.GroupCode != null) // 不显示 WebConfig 分组
            .WhereIF(groupCode.NotNullOrWhiteSpace(), u => u.GroupCode == groupCode)
            .GroupBy(u => u.GroupCode)
            .Select(u => u.GroupCode).ToListAsync();
    }
}
